package com.cardone.common.util;

import java.math.BigDecimal;

import org.apache.commons.lang.math.IntRange;

import com.cardone.common.dto.PaginationDto;

/**
 * 分页工具类
 *
 * @author yaohaitao
 */
public class PaginationUtils {
	/**
	 * 修正开始行数
	 */
	private static int fixBeginRowNum = -1;

	/**
	 * 分页行数大小
	 */
	private static int size = 10;

	/**
	 * 显示代码数量范围
	 */
	private static int viewNoNum = 6;

	/**
	 * 获取：分页行数大小
	 *
	 * @return 分页行数大小
	 */
	public static int getSize() {
		return PaginationUtils.size;
	}

	/**
	 * 获取：显示代码数量范围
	 *
	 * @return 显示代码数量范围
	 */
	public static int getViewNoNum() {
		return PaginationUtils.viewNoNum;
	}

	/**
	 * 实例化：分页
	 *
	 * @param no
	 *          页面代码
	 * @param size
	 *          分页行数大小
	 * @param viewNoNum
	 *          显示代码数量范围
	 * @param totalSize
	 *          总数量
	 * @return 分页
	 */
	public static <T> PaginationDto<T> newPagination(final int no, final int size, final int viewNoNum, final long totalSize) {
		final PaginationDto<T> pagination = new PaginationDto<T>();

		if (totalSize < 1) {
			return pagination;
		}

		pagination.setTotalSize(totalSize);

		if (size < 1) {
			pagination.setSize(PaginationUtils.size);
		} else {
			pagination.setSize(Math.max(size, PaginationUtils.size));
		}

		// 向上取整: 1.01 = 2
		final int totalNo = new java.math.BigDecimal(totalSize).divide(new BigDecimal(pagination.getSize()), BigDecimal.ROUND_UP).toBigInteger().intValue();

		pagination.setTotalNo(totalNo);

		pagination.setFirstNo(1);

		pagination.setNo(Math.min(Math.max(no, 1), totalNo));

		pagination.setHasFirstNo(pagination.getNo() > 1);

		pagination.setPreviousNo(Math.max(pagination.getNo() - 1, 1));

		pagination.setHasPreviousNo(pagination.isHasFirstNo());

		pagination.setNextNo(Math.min(pagination.getNo() + 1, totalNo));

		pagination.setHasNextNo(pagination.getNo() < pagination.getTotalNo());

		pagination.setLastNo(totalNo);

		pagination.setHasLastNo(pagination.isHasNextNo());

		pagination.setEndRowNum(pagination.getNo() * pagination.getSize());

		pagination.setBeginRowNum(pagination.getEndRowNum() - (pagination.getSize() + PaginationUtils.fixBeginRowNum));

		if (viewNoNum < 1) {
			return pagination;
		}

		final int newViewNoNum = Math.max(viewNoNum, PaginationUtils.viewNoNum);

		final int viewNoNumHalf = new java.math.BigDecimal(newViewNoNum).divide(new BigDecimal(2), BigDecimal.ROUND_HALF_UP).toBigInteger().intValue();

		int startNo = Math.max(pagination.getNo() - viewNoNumHalf, 1);

		final int endNo = Math.min((startNo + newViewNoNum) - 1, totalNo);

		if (((endNo - startNo) + 1) < newViewNoNum) {
			startNo = Math.max((endNo - newViewNoNum) + 1, 1);
		}

		final int[] nos = new IntRange(startNo, endNo).toArray();

		pagination.setNos(nos);

		return pagination;
	}

	/**
	 * 实例化：分页
	 *
	 * @param no
	 *          页面代码
	 * @param size
	 *          分页行数大小
	 * @param totalSize
	 *          总数量
	 * @return 分页
	 */
	public static <T> PaginationDto<T> newPagination(final int no, final int size, final long totalSize) {
		return PaginationUtils.newPagination(no, size, 0, totalSize);
	}

	/**
	 * 实例化：分页
	 *
	 * @param no
	 *          页面代码
	 * @param totalSize
	 *          总数量
	 * @return 分页
	 */
	public static <T> PaginationDto<T> newPagination(final int no, final long totalSize) {
		return PaginationUtils.newPagination(no, PaginationUtils.size, 0, totalSize);
	}

	/**
	 * 设置：修正开始行数
	 *
	 * @param fixBeginRowNum
	 *          修正开始行数
	 */
	public static void setFixBeginRowNum(final int fixBeginRowNum) {
		PaginationUtils.fixBeginRowNum = fixBeginRowNum;
	}

	/**
	 * 设置：分页行数大小
	 *
	 * @param size
	 *          分页行数大小
	 */
	public static void setSize(final int size) {
		PaginationUtils.size = size;
	}

	/**
	 * 设置：显示代码数量范围
	 *
	 * @param viewNoNum
	 *          显示代码数量范围
	 */
	public static void setViewNoNum(final int viewNoNum) {
		PaginationUtils.viewNoNum = viewNoNum;
	}
}